import { HttpException, Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository } from 'typeorm'
import { JwtService } from '@nestjs/jwt'
import { UserEntity } from '../user/entities/user.entity'
import { ListWalletLogDto } from './dto/list-points.dto'
import { WalletLogEntity } from './entities/points.entity'

@Injectable()
export class WalletLogService {
  constructor(
    @InjectRepository(WalletLogEntity)
    private readonly walletLogRepository: Repository<WalletLogEntity>,
    @InjectRepository(UserEntity)
    private readonly userRepository: Repository<UserEntity>,
    private readonly jwtService: JwtService
  ) { }

  // 钱包明细列表
  async list(data: ListWalletLogDto & { user_id: number }) {
    const { page, pageSize, type = -1, user_id } = data

    const qb = this.walletLogRepository.createQueryBuilder('wallet_log')
    qb.orderBy('wallet_log.create_time', 'DESC')
    qb.andWhere('wallet_log.user_id = :user_id', { user_id })

    const EXCLUDE_TYPE = 5
    if (+type === 1) {
      // 返回数据库中type不等于5的数据
      qb.andWhere('wallet_log.type != :excludeType', { excludeType: EXCLUDE_TYPE })
    } else if (+type === 2) {
      qb.andWhere('wallet_log.type = :includeType', { includeType: EXCLUDE_TYPE })
    }

    if (!page && !pageSize) {
      const entries = (await qb.getMany()).map(({ user_id, ...rest }) => ({
        ...rest,
        fee: rest.type !== 5 ? `+${rest.fee}` : `${rest.fee}`
      }))
      return {
        entries,
        total: entries.length
      }
    }
    const pageNum = Math.max(1, Number(page) || 1)
    const pageSizeNum = Math.min(100, Math.max(1, Number(pageSize) || 10))
    const total = await qb.getCount()
    const temp = (await qb.skip((pageNum - 1) * pageSizeNum).take(pageSizeNum).getMany()).map(({ user_id, ...rest }) => ({
      ...rest,
      fee: rest.type !== 5 ? `+${rest.fee}` : `${rest.fee}`
    }))

    return {
      entries: temp,
      total
    }
  }

  // 新建钱包交易记录
  async createTransaction(userId: number, type: number, fee: number) {
    if (fee <= 0) {
      throw new HttpException('余额必须为正数', 400)
    }
    return this.walletLogRepository.manager.transaction(async (manager) => {
      const finalFee = type === 5 ? -fee : fee
      const transaction = this.walletLogRepository.create({
        user_id: userId,
        type,
        fee: finalFee,
        create_time: Math.floor(Date.now() / 1000)
      })
      const temp = await manager.save(transaction)

      // 更新用户的积分余额
      await manager.update(UserEntity, userId, {
        balance: () => `balance + ${finalFee}`
      })
      return temp
    })
  }
}
